home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
iguana
/
incosrc
/
incosrc.exe
/
MIRRBALL
/
PATH
/
SPLIN.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1994-06-09
|
11KB
|
508 lines
USES Crt, Objects, Matrix;
FUNCTION POW2(a : DOUBLE): DOUBLE;
BEGIN
POW2 := a*a
END;
FUNCTION POW3(a : DOUBLE): DOUBLE;
BEGIN
POW3 := a*a*a
END;
FUNCTION TAN(a : DOUBLE): DOUBLE;
BEGIN
TAN := Sin(a)/Cos(a)
END;
{ --------------------------------- }
TYPE
Pt = RECORD
f, t, slope : DOUBLE;
a, b, c, d : DOUBLE
END;
PtArray = RECORD
npts : INTEGER;
pts : ARRAY [1..200] OF Pt;
END;
PROCEDURE CalcSlopes(VAR pa: PtArray);
VAR
i : INTEGER;
BEGIN
FOR i := 1 TO pa.npts DO BEGIN
IF i = 1 THEN
pa.pts[i].slope := (pa.pts[i+1].f-pa.pts[i].f) /
(pa.pts[i+1].t-pa.pts[i].t)
ELSE IF i = pa.npts THEN
pa.pts[i].slope := (pa.pts[i].f-pa.pts[i-1].f) /
(pa.pts[i].t-pa.pts[i-1].t)
ELSE
pa.pts[i].slope := TAN(
(ARCTAN((pa.pts[i+1].f-pa.pts[i].f) /
(pa.pts[i+1].t-pa.pts[i].t)) +
ARCTAN((pa.pts[i].f-pa.pts[i-1].f) /
(pa.pts[i].t-pa.pts[i-1].t)))/2);
{WriteLn('Pendiente calculada: ', pa.pts[i].slope);}
END
END;
PROCEDURE CalcCoeffs(VAR pa: PtArray);
VAR
i : INTEGER;
ma, m1 : Matrix4x4;
da, d1 : DOUBLE;
b : Column4;
BEGIN
CalcSlopes(pa);
ma[4,1] := 1;
ma[4,2] := 1;
ma[3,3] := 1;
ma[3,4] := 1;
ma[4,3] := 0;
ma[4,4] := 0;
FOR i := 1 TO pa.npts-1 DO BEGIN
b[1] := pa.pts[i].f;
b[2] := pa.pts[i+1].f;
b[3] := pa.pts[i].slope;
b[4] := pa.pts[i+1].slope;
ma[3,1] := pa.pts[i].t;
ma[3,2] := pa.pts[i+1].t;
ma[2,3] := pa.pts[i].t*2;
ma[2,4] := pa.pts[i+1].t*2;
ma[2,1] := POW2(pa.pts[i].t);
ma[2,2] := POW2(pa.pts[i+1].t);
ma[1,3] := POW2(pa.pts[i].t)*3;
ma[1,4] := POW2(pa.pts[i+1].t)*3;
ma[1,1] := POW3(pa.pts[i].t);
ma[1,2] := POW3(pa.pts[i+1].t);
da := Determinante4(ma);
PrepareMatrix(m1, ma, b, 1);
d1 := Determinante4(m1);
pa.pts[i].a := d1/da;
PrepareMatrix(m1, ma, b, 2);
d1 := Determinante4(m1);
pa.pts[i].b := d1/da;
PrepareMatrix(m1, ma, b, 3);
d1 := Determinante4(m1);
pa.pts[i].c := d1/da;
PrepareMatrix(m1, ma, b, 4);
d1 := Determinante4(m1);
pa.pts[i].d := d1/da;
{ WriteLn('Calculados coeficientes del segmento ',i, ',')}
END;
END;
{ ----------------------------------- }
FUNCTION Interpolate(VAR pf: PtArray; x : DOUBLE): DOUBLE;
VAR
i : INTEGER;
BEGIN
Interpolate := 0;
FOR i := 2 TO pf.npts-2 DO
IF (x >= pf.pts[i].t) AND (x <= pf.pts[i+1].t) THEN
Interpolate := pf.pts[i].a*POW3(x) +
pf.pts[i].b*POW2(x) +
pf.pts[i].c* x +
pf.pts[i].d
END;
{ ----------------------------------- }
VAR
PF1, PF2, PF3 : PtArray;
PROCEDURE ReadPtList(FName: STRING);
VAR
fi : TEXT;
i : INTEGER;
t, f1,
f2, f3 : DOUBLE;
BEGIN
Assign(fi, FName);
Reset(fi);
i := 1;
WHILE (i <= 200) AND NOT Eof(fi) DO BEGIN
t := -1;
ReadLn(fi, t, f1, f2, f3);
IF t < 0 THEN BEGIN
PF1.npts := i-1;
PF2.npts := i-1;
PF3.npts := i-1;
Close(fi);
EXIT
END;
PF1.pts[i].t := t;
PF2.pts[i].t := t;
PF3.pts[i].t := t;
PF1.pts[i].f := f1;
PF2.pts[i].f := f2;
PF3.pts[i].f := f3;
{ WriteLn('Leido...');}
INC(i)
END;
PF1.npts := i-1;
PF2.npts := i-1;
PF3.npts := i-1;
Close(fi);
END;
PROCEDURE WritePtList(FName: STRING);
VAR
fi : TEXT;
i : INTEGER;
t, f1, f2 : DOUBLE;
BEGIN
Assign(fi, FName);
Rewrite(fi);
FOR i := 1 TO PF1.npts DO BEGIN
WriteLn(fi, PF1.pts[i].t : 10 : 1, PF1.pts[i].f : 10 : 1, PF2.pts[i].f : 10 : 1, PF3.pts[i].f : 10 : 1);
END;
Close(fi);
END;
{ ----------------------------------- }
TYPE
TScr = ARRAY[0..199,0..319] OF BYTE;
VAR
Screen : TScr ABSOLUTE $A000:0;
PROCEDURE Usage;
BEGIN
WriteLn('Cubic Spline Generator v0.5, (C) 1993 bye Jare/Iguana');
WriteLn(' Usage: PATH nsteps [infile]');
HALT
END;
VAR
i : INTEGER;
fi : TEXT;
t, x, y, z : DOUBLE;
NFrames : INTEGER;
Pant : ^TScr;
CONST
MI : Matrix4x4 = ((1.0, 2.0, 3.0, 4.0),
(5.0, 9.0, 8.0, 7.0),
(3.0, 2.0, 1.0, 9.0),
(4.0, 2.0, 6.0, 7.0));
PROCEDURE DumpPal;
BEGIN
Port[$3C8] := 64;
FOR i := 16 TO 63 DO
BEGIN
Port[$3C9] := i;
Port[$3C9] := i;
Port[$3C9] := i;
END;
END;
PROCEDURE Pinta;
BEGIN
IF PF1.npts >= 3 THEN
BEGIN
CalcCoeffs(PF1);
CalcCoeffs(PF2);
CalcCoeffs(PF3);
Screen := Pant^;
FOR i := 0 TO NFrames-1 DO BEGIN
t := i*(PF1.pts[PF1.npts-1].t - PF1.pts[2].t)/NFrames +
PF1.pts[2].t;
x := Interpolate(PF1,t);
y := Interpolate(PF2,t);
z := Interpolate(PF3,t);
IF z > 11.0 THEN z := 11.0;
IF z < -36.0 THEN z := -36.0;
Screen[ROUND(y), ROUND(x)] := ROUND(z)+36+64;
END;
END;
FOR i := 1 TO PF1.npts DO BEGIN
t := PF1.pts[i].t;
x := PF1.pts[i].f;
y := PF2.pts[i].f;
Screen[ROUND(y), ROUND(x) ] := 10;
Screen[ROUND(y)+1, ROUND(x) ] := 10;
Screen[ROUND(y), ROUND(x)+1] := 10;
Screen[ROUND(y)-1, ROUND(x) ] := 10;
Screen[ROUND(y), ROUND(x)-1] := 10;
END;
END;
PROCEDURE Salva;
VAR
ot, ox, oy, oz : INTEGER;
f : FILE OF BYTE;
b : BYTE;
BEGIN
IF PF1.npts >= 3 THEN
BEGIN
Assign(f, 'POINTS.DAT');
Rewrite(f);
b := LO(NFrames);
Write(f, b);
b := HI(NFrames);
Write(f, b);
t := PF1.pts[2].t;
ox := ROUND(Interpolate(PF1,t));
oy := ROUND(Interpolate(PF2,t));
oz := ROUND(Interpolate(PF3,t));
IF oz > 11 THEN z := 11;
IF oz < -36 THEN z := -36;
ot := ROUND(t);
FOR i := 0 TO NFrames-1 DO BEGIN
t := i*(PF1.pts[PF1.npts-1].t - PF1.pts[2].t)/NFrames +
PF1.pts[2].t;
x := Interpolate(PF1,t);
y := Interpolate(PF2,t);
z := Interpolate(PF3,t);
IF z > 11.0 THEN z := 11.0;
IF z < -36.0 THEN z := -36.0;
b := (ROUND(x) - ox) AND $FF;
Write(f, b);
b := (ROUND(y) - oy) AND $FF;
Write(f, b);
b := (ROUND(z) - oz) AND $FF;
Write(f, b);
ox := ROUND(x);
oy := ROUND(y);
oz := ROUND(z);
END;
Close(f);
END;
END;
VAR
mx, my,
mt, mz : INTEGER;
b : BYTE;
l : LONGINT;
d : WORD;
PROCEDURE RePinta;
BEGIN
ASM
MOV AX,2
INT 33h
END;
NFrames := mt DIV 4;
Pinta;
ASM
MOV AX,1
INT 33h
END;
END;
PROCEDURE EscribeZ;
BEGIN
FillChar(Screen[200-8, 0], 320*8, 12);
GotoXY(1, 25);
DirectVideo := FALSE;
Write(mz : 6 );
END;
VAR
St : TDosStream;
LABEL
Fin;
BEGIN
NEW(Pant);
St.Init('..\..\graf\monoigua.pix', stOpenRead);
St.Read(Pant^, 64000);
St.Done;
ASM
MOV AX,13h
INT 10h
XOR AX,AX
INT 33h
MOV AX,1
INT 33h
END;
DumpPal;
mz := -36;
PF1.npts := 0;
PF2.npts := 0;
PF3.npts := 0;
t := 100;
REPEAT
IF KeyPressed THEN
BEGIN
CASE ReadKey OF
#0 : ReadKey;
's',
'S' : BEGIN
WritePtList('ptlist.txt');
END;
'l',
'L' : BEGIN
ReadPtList('ptlist.txt');
mt := ROUND(PF1.pts[PF1.npts].t);
RePinta;
END;
'+' : BEGIN
INC(mz);
EscribeZ;
END;
'-' : BEGIN
DEC(mz);
EscribeZ;
END;
#27 : GOTO Fin;
END;
END;
ASM
MOV AX,3
INT 33h
SHR CX,1
MOV [mx],CX
MOV [my],DX
MOV [b],BL
END;
IF (b AND 1) <> 0 THEN
BEGIN
WHILE (b AND 1) <> 0 DO
ASM
MOV AX,3
INT 33h
SHR CX,1
MOV [mx],CX
MOV [my],DX
MOV [b],BL
END;
INC(mt, 100);
INC(PF1.npts);
INC(PF2.npts);
INC(PF3.npts);
PF1.pts[PF1.npts].t := mt;
PF2.pts[PF2.npts].t := mt;
PF3.pts[PF3.npts].t := mt;
PF1.pts[PF1.npts].f := mx;
PF2.pts[PF2.npts].f := my;
PF3.pts[PF3.npts].f := mz;
RePinta;
END;
IF (b AND 2) <> 0 THEN
BEGIN
l := $7FFFFFFF;
d := 1;
FOR i := 1 TO PF1.npts DO
IF l > ROUND ((mx-PF1.pts[i].f)*(mx-PF1.pts[i].f) +
(my-PF2.pts[i].f)*(my-PF2.pts[i].f)) THEN
BEGIN
l := ROUND((mx-PF1.pts[i].f)*(mx-PF1.pts[i].f) +
(my-PF2.pts[i].f)*(my-PF2.pts[i].f));
d := i;
END;
WHILE (b AND 2) <> 0 DO
ASM
MOV AX,3
INT 33h
SHR CX,1
MOV [mx],CX
MOV [my],DX
MOV [b],BL
END;
PF1.pts[d].f := mx;
PF2.pts[d].f := my;
PF3.pts[d].f := mz;
RePinta;
END;
UNTIL FALSE;
Fin:
ASM
MOV AX,3
INT 10h
END;
Salva;
END.